#include "../include/xmlparser.h"

/* Internal prototypes */
xmlNodePtr getnode(xmlNodePtr node, char * nodename);

xmlDocPtr xml_loaddoc(char * xmlfile)
{
    xmlDocPtr doc = NULL;
    xmlNodePtr node = NULL;

    /* Load the XML file and error check */
	doc = xmlParseFile(xmlfile);

	if(doc == NULL)
	{
		printf("ERROR: Could not load %s\n", xmlfile);
		xml_freedoc(doc);
		return NULL;
	}

	/* Check that the file is not empty */
	node = xmlDocGetRootElement(doc);

	if(node == NULL)
	{
		printf("ERROR: Document %s is empty\n", xmlfile);
		xml_freedoc(doc);
		return NULL;
	}

	return doc;
}

void xml_freedoc(xmlDocPtr doc)
{
    xmlFreeDoc(doc);
}

xmlNodePtr xml_getroot(xmlDocPtr doc, char * name)
{
    xmlNodePtr node = NULL;

    /* Check if the file is valid (containing a root node) */
    node = xmlDocGetRootElement(doc);
	if (xmlStrcmp(node->name, (const xmlChar *) name))
	{
		printf("ERROR: XML Document does not contain '%s' as root node!\n", name);
		return NULL;
	}

	return node;
}

xmlNodePtr xml_getnode(xmlNodePtr node, char * nodenames)
{
    int from = 0;

    for(int i = 0; i <= strlen(nodenames); i++)
    {
        /* If it encounters a ->, read the nodename before it */
        if(nodenames[i] == '-' || nodenames[i+1] == '>')
        {
            /* Malloc and copy the segment of the nodename */
            char * nod = malloc(i-from+1);
            memcpy(nod, nodenames+from, i-from);
            nod[i-from] = 0;

            /* Get the actual node */
            node = getnode(node, nod);

            /* Make the from integer big enough to skip the next -> */
            from = i + 2;

            /* Free the nodename segment */
            free(nod);
        } else {
            /* If it doesent encounter a ->, or its the last node, read it */
            if(i == strlen(nodenames))
            {
                char * nod = malloc(i-from+1);
                memcpy(nod, nodenames+from, i-from);
                nod[i-from] = 0;

                node = getnode(node, nod);

                free(nod);
            }
        }
    }

    return node;
}


xmlNodePtr getnode(xmlNodePtr node, char * nodename)
{
    node = node->xmlChildrenNode;

	while (node != NULL)
	{
		if((!xmlStrcmp(node->name, (const xmlChar *)nodename)))
            return node;
        node = node->next;
	}
	return NULL;
}

void * xml_readnode(xmlDocPtr doc, xmlNodePtr node, char * nodename)
{
	xmlChar * val;
	node = node->xmlChildrenNode;

	while (node != NULL)
	{
	    if ((!xmlStrcmp(node->name, (const xmlChar *)nodename))) {
		    val = xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
		    return val;
 	    }
        node = node->next;
	}
    return NULL;
}

void * xml_readattrib(xmlDocPtr doc, xmlNodePtr cur, char * nodename, xmlChar * attrib) {

	xmlChar *val = NULL;
	cur = cur->xmlChildrenNode;
	while (cur != NULL) {
	    if ((!xmlStrcmp(cur->name, (const xmlChar *)nodename))) {
            val = xmlGetProp(cur, attrib);
	    }
	    cur = cur->next;
	}
	return val;
}

